home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
extrac.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
14KB
|
423 lines
; $Id: extrac.pro,v 1.4 1997/01/15 03:11:50 ali Exp $
;
; Copyright (c) 1989-1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
function EXTRAC, Array, P0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15
;+
; NAME:
; EXTRAC
;
; PURPOSE:
; The EXTRAC function returns as its result any rectangular sub-matrix
; or portion of the parameter array. When parts of the specified
; subsection lie outside the bounds of the array, zeros are
; entered into these outlying elements.
;
; EXTRAC was originally a built-in system procedure in the PDP-11
; version of IDL, and was retained in that form in the original VAX/VMS
; IDL for compatibility. Most applications of the EXTRAC function
; are more concisely written using subscript ranges (e.g., X(10:15)). In
; the current release of IDL, EXTRAC has been rewritten as a User Library
; function that provides the same interface as the previous versions.
;
; CATEGORY:
; Array Manipulation.
;
; CALLING SEQUENCE:
; Result = EXTRAC(Array, C1, C2, ..., Cn, S1, S2, ..., Sn)
;
; INPUTS:
; Array: The array from which the subarray will be copied.
;
; Ci: The starting subscript in Array for the subarray. There
; should be one Ci for each dimension of Array.
;
; Si: The size of each dimension. The result will have dimensions
; of (S1, S2, ..., Sn). There should be one Si for each
; dimension of Array.
;
; OUTPUTS:
; This function returns a two-dimensional, floating-point,
; interpolated array.
;
; RESTRICTIONS:
; In order to make the most typical cases run quickly, little error
; checking is done on the input. In particular, the Ci and Si arguments
; must all be scalar integers, and the Si must be non-negative.
;
; If you know that the subarray will never lie beyond the edges of
; the array, it is more efficient to use array subscript ranges
; to extract the data instead of EXTRAC.
;
; PROCEDURE:
; If the subarray lies entirely inside the Array argument, the
; standard array subscript-range mechanism is used to do the work.
; Otherwise, a zeroed array of the correct type and size is
; created, and the overlapping subarray is copied into it.
;
; EXAMPLES:
; EXAMPLE 1:
; Define a 1000 point vector with each element initialized to
; its subscript. Extract a 300 pt. vector, starting at A(200) and
; going to A(499). B(0) will be equal to A(200), B(299) will be
; equal to A(499). Enter:
;
; A = FINDGEN(1000)
; B = EXTRAC(A, 200, 300)
;
; EXAMPLE 2:
; Here, the first 49 points extracted (B(0) to B(49)) lie outside
; the bounds of the vector and are set to 0. B(50) is set to A(0),
; B(51) is set to A(1) which is 1, ... Enter:
;
; A = FINDGEN(1000)
; B = EXTRAC(A, -50, 100)
;
; EXAMPLE 3:
; The following commands illustrate the use of EXTRAC with multi-
; dimensional arrays. Enter:
;
; A = INTARR(64,64) ;Make a 64X64 matrix to play with
;
; Take out a 32X32 portion starting at A(20,30) by entering:
;
; B = EXTRAC(A, 20, 30, 32, 32)
;
; A better way to perform the same operation as the previous line is:
;
; B = A(20:51, 30:61)
;
; Extract the 20th column and 32nd row of A:
;
; B = EXTRAC(A, 19, 0, 1, 64) ; Extract 20th column of A
; B = EXTRAC(A, 0, 31, 64, 1) ; Extract 32nd row of A
;
; Take a 32X32 matrix from A starting at A(40,50).
;
; B = EXTRAC(A, 40, 50, 32, 32)
;
; NOTE: Those points beyond the boundaries of A are set to 0.
;
; REVISION HISTORY:
; July 18, 1989 Written AB, RSI
;-
on_error, 2 ; Return to caller on error
asize = SIZE(Array)
ndim = asize[0]
orig_dims = asize[1:ndim]
; Is it an array?
if (ndim eq 0) then message, 'Target argument must be an array.'
; Is there an appropriate number of arguments present?
if (n_params() ne (ndim * 2 + 1)) then message, 'Wrong number of arguments.'
; Convert the arguments to a more convenient form.
args = intarr(2 * ndim)
CASE (ndim) of
; 8: BEGIN & args[15] = P15 & args[14] = P14 & GOTO, do_seven & END
7: do_seven: BEGIN & args[13] = P13 & args[12] = P12 & GOTO, do_six & END
6: do_six: BEGIN & args[11] = P11 & args[10] = P10 & GOTO, do_five & END
5: do_five: BEGIN & args[9] = P9 & args[8] = P8 & GOTO, do_four & END
4: do_four: BEGIN & args[7] = P7 & args[6] = P6 & GOTO, do_three & END
3: do_three: BEGIN & args[5] = P5 & args[4] = P4 & GOTO, do_two & END
2: do_two: BEGIN & args[3] = P3 & args[2] = P2 & GOTO, do_one & END
1: do_one: BEGIN & args[1] = P1 & args[0] = P0 & END
ENDCASE
srt = args[0:ndim-1]
dims = args[ndim:*]
; Determine if the subarray extends beyond the edges of the original.
; If not, a simple expression will do the job.
srt_over = where(srt lt 0, s_cnt)
dims_over = where((srt + dims) gt orig_dims, b_cnt)
if ((s_cnt eq 0) and (b_cnt eq 0)) then begin
; The extracted array does not go beyond the array boundaries. Use the
; normal expression to extract the result.
bnd = dims + srt - 1
case (ndim) of
1: result = Array[P0:bnd[0]]
2: result = Array[P0:bnd[0],P1:bnd[1]]
3: result = Array[P0:bnd[0],P1:bnd[1],P2:bnd[2]]
4: result = Array[P0:bnd[0],P1:bnd[1],P2:bnd[2],P3:bnd[3]]
5: result = Array[P0:bnd[0],P1:bnd[1],P2:bnd[2],P3:bnd[3],P4:bnd[4]]
6: result = Array[P0:bnd[0],P1:bnd[1],P2:bnd[2],P3:bnd[3],P4:bnd[4], $
P5:bnd[5]]
7: result = Array[P0:bnd[0],P1:bnd[1],P2:bnd[2],P3:bnd[3],P4:bnd[4], $
P5:bnd[5],P6:bnd[6]]
; 8: result = Array[P0:bnd[0],P1:bnd[1],P2:bnd[2],P3:bnd[3],P4:bnd[4], $
; P5:bnd[5],P6:bnd[6],P7:bnd[7]]
endcase
goto, done
endif
; If we get this far, the sub array extends beyond the source array
; dimensions. Get a zeroed array of the correct type and extract the
; non-zero part of the original into it.
result = make_array(type=asize[ndim + 1], dimension=dims) ; Get a result array
; Determine the insertion point for the subarray.
isrt = intarr(ndim)
if (s_cnt ne 0) then isrt[srt_over] = abs(srt[srt_over])
; If any of the starting points exceed the dimensions, then we're done.
dims_over = where(isrt ge dims, b_cnt)
srt_over = where(srt ge orig_dims, s_cnt)
if ((b_cnt ne 0) or (s_cnt ne 0)) then goto, done
; Determine the size of the subarray to be inserted. This is the
; lesser of the original size and the room for insertion in the target.
;
; dims - isrt is the availible room in the result array
; orig_dims - srt - is the largest possible subarray we can pull out of ARRAY
t1 = dims - isrt
bnd = (t1 < (orig_dims - srt)) < t1 ; Minimum of the two sizes
srt = srt > 0 ; Clip starting point to non-negative
bnd = srt + bnd - 1 ; Calcualte the actual outer boundary
; Insert the subarray from ARRAY into RESULT
case (ndim) of
1: result[isrt[0]] = Array[srt[0]:bnd[0]]
2: result[isrt[0],isrt[1]] = Array[srt[0]:bnd[0],srt[1]:bnd[1]]
3: result[isrt[0],isrt[1],isrt[2]] = Array[srt[0]:bnd[0],srt[1]:bnd[1],srt[2]:bnd[2]]
4: result[isrt[0],isrt[1],isrt[2],isrt[3]] = $
Array[srt[0]:bnd[0],srt[1]:bnd[1],srt[2]:bnd[2],srt[3]:bnd[3]]
5: result[isrt[0],isrt[1],isrt[2],isrt[3],isrt[4]] = $
Array[srt[0]:bnd[0],srt[1]:bnd[1],srt[2]:bnd[2],srt[3]:bnd[3], $
srt[4]:bnd[4]]
6: result[isrt[0],isrt[1],isrt[2],isrt[3],isrt[4],isrt[5]] = $
Array[srt[0]:bnd[0],srt[1]:bnd[1],srt[2]:bnd[2],srt[3]:bnd[3], $
srt[4]:bnd[4], srt[5]:bnd[5]]
7: result[isrt[0],isrt[1],isrt[2],isrt[3],isrt[4],isrt[5],isrt[6]] = $
Array[srt[0]:bnd[0],srt[1]:bnd[1],srt[2]:bnd[2],srt[3]:bnd[3], $
srt[4]:bnd[4], srt[5]:bnd[5],srt[6]:bnd[6]]
; 8: result[isrt[0],isrt[1],isrt[2],isrt[3],isrt[4],isrt[5],isrt[6],isrt[7]]= $
; Array[srt[0]:bnd[0],srt[1]:bnd[1],srt[2]:bnd[2],srt[3]:bnd[3], $
; srt[4]:bnd[4], srt[5]:bnd[5],srt[6]:bnd[6],srt[7]:bnd[7]]
endcase
done:
return, result
end
; The rest of this file exists in order to test the EXTRAC procedure above.
; Normally, it won't be compiled when EXTRAC is used because when
; a procedure is automatically pulled out of the user library, only
; enough is compiled to get the desired routine, the rest of the file
; is ignored. Use ".run extrac" to compile everything.
pro extrac_errprint, n, is, want
; extrac_errprint tests a result against the desired value and
; reports it if they don't agree
;
; entry:
; n - Error identification number.
; is - Result value.
; want - Correct value for is.
;
; exit:
; if (is eq want) then errprint returns quietly. Otherwise,
; it sends a report to stderr.
;
if (size(is))[0] eq 0 then begin
if is ne want then begin
printf,-2,format='($,"ERROR(",a,"): ")', strtrim(n,2)
printf,-2,format='(" is(",a,"), want(",a,")")',is,want
endif else goto, is_ok
endif else begin
s = size(is)
if s[s[0]+1] eq 7 then $ ;Strings?
x = total(is ne want) $
else x = total(abs(is-want))
if x ne 0. then begin
printf,-2,format='($,"ERROR(",a,"): ")', strtrim(n,2)
printf,-2,format='(" ARRAY total is(",a,"), want(",a,")")',x,0.0
endif else goto, is_ok
endelse
return
is_ok:
printf, -2, format='("OK(", I0, ")")', n
end
pro test_extrac
; Test the EXTRAC procedure. These tests are hardly exhaustive ---
; especially with dimensions above 2.
;;;;;;;;;;; PART 1 --- Vector case
a = findgen(10) ; Test data
; Desired subarray is completely to left of the array
extrac_errprint, 1, extrac[a, -100, 60], fltarr(60)
; Subarray is completely to right of the array
extrac_errprint, 2, extrac[a, 100, 60], fltarr(60)
; Subarray overlaps partly on left
correct = fltarr(10)
correct[5] = a[0:4]
extrac_errprint, 3, extrac[a, -5, 10], correct
; Subarray overlaps partly on right
correct = fltarr(10)
correct[0] = a[5:9]
extrac_errprint, 4, extrac[a, 5, 10], correct
; Border Condition - Just left of array
extrac_errprint, 5, extrac[a, -10, 10], fltarr(10)
; Condition Border - One column overlaps on right
correct = fltarr(10)
correct[9] = a[0]
extrac_errprint, 6, extrac[a, -9, 10], correct
; Border Condition - Just right of array
extrac_errprint, 7, extrac[a, 10, 10], fltarr(10)
; Condition Border - One column overlaps on left
correct = fltarr(10,10)
correct[0] = a[9]
extrac_errprint, 8, extrac[a, 9, 10], correct
; Trivial case --- extract the entire array
extrac_errprint, 9, extrac[a, 0, 10], a
; Extract a completely interior region. This is what the subscript op does
extrac_errprint, 10, extrac[a, 2, 5], a[2:6]
;;;;;;;;;;; PART 2 --- 2D case
a = findgen(10,10) ; Test data
; Desired subarray is completely below the array
extrac_errprint, 11, extrac[a, -100, -100, 60, 60], fltarr(60, 60)
; Subarray is completely above the array
extrac_errprint, 12, extrac[a, 100, 100, 60, 60], fltarr(60, 60)
; Subarray overlaps partly on left
correct = fltarr(10,10)
correct[5,0] = a[0:4, 0:*]
extrac_errprint, 13, extrac[a, -5, 0, 10, 10], correct
; Subarray overlaps partly on right
correct = fltarr(10,10)
correct[0,0] = a[5:9, 0:*]
extrac_errprint, 14, extrac[a, 5, 0, 10, 10], correct
; Subarray overlaps partly on top
correct = fltarr(10,10)
correct[0,5] = a[0:*, 0:4]
extrac_errprint, 15, extrac[a, 0, -5, 10, 10], correct
; Subarray overlaps partly on bottom
correct = fltarr(10,10)
correct[0,0] = a[*, 5:9]
extrac_errprint, 16, extrac[a, 0, 5, 10, 10], correct
; Border Condition - Just left of array
extrac_errprint, 17, extrac[a, -10, 0, 10, 10], fltarr(10,10)
; Condition Border - One column overlaps on right
correct = fltarr(10,10)
correct[9,0] = a[0,*]
extrac_errprint, 18, extrac[a, -9, 0, 10, 10], correct
; Border Condition - Just right of array
extrac_errprint, 19, extrac[a, 10, 0, 10, 10], fltarr(10,10)
; Condition Border - One column overlaps on left
correct = fltarr(10,10)
correct[0,0] = a[9,*]
extrac_errprint, 20, extrac[a, 9, 0, 10, 10], correct
; Trivial case --- extract the entire array
extrac_errprint, 21, extrac[a, 0, 0, 10, 10], a
; Extract a completely interior region. This is what the subscript op does
extrac_errprint, 22, extrac[a, 2, 3, 5, 6], a[2:6,3:8]
;;;;;;;;;;; PART 3 --- 3D case
a = findgen(10,10,10) ; Test data
; Desired subarray is completely below the array
extrac_errprint, 23, extrac[a,-100,-100,-100,60,60,60], fltarr(60,60,60)
; Subarray is completely above the array
extrac_errprint, 24, extrac[a, 100, 100, 100, 60, 60, 60], fltarr(60,60,60)
; Subarray overlaps partly on left
correct = fltarr(10,10,10)
correct[5,0,0] = a[0:4, 0:*, 0:*]
extrac_errprint, 25, extrac[a, -5, 0, 0, 10, 10, 10], correct
; Subarray overlaps partly on right
correct = fltarr(10,10,10)
correct[0,0,0] = a[5:9, 0:*, 0:*]
extrac_errprint, 26, extrac[a, 5, 0, 0, 10, 10, 10], correct
; Subarray overlaps partly on top
correct = fltarr(10,10,10)
correct[0,5,0] = a[0:*, 0:4, 0:*]
extrac_errprint, 27, extrac[a, 0, -5, 0, 10, 10, 10], correct
; Subarray overlaps partly on bottom
correct = fltarr(10,10,10)
correct[0,0,0] = a[*, 5:9,*]
extrac_errprint, 28, extrac[a, 0, 5, 0, 10, 10, 10], correct
; Border Condition - Just left of array
extrac_errprint, 29, extrac[a, -10, 0, 0, 10, 10, 10], fltarr(10,10,10)
; Condition Border - One column overlaps on right
correct = fltarr(10,10,10)
correct[9,0,0] = a[0,*,*]
extrac_errprint, 30, extrac[a, -9, 0, 0, 10, 10, 10], correct
; Border Condition - Just right of array
extrac_errprint, 31, extrac[a, 10, 0, 0, 10, 10, 10], fltarr(10,10,10)
; Condition Border - One column overlaps on left
correct = fltarr(10,10,10)
correct[0,0,0] = a[9,*,*]
extrac_errprint, 32, extrac[a, 9, 0, 0, 10, 10, 10], correct
; Trivial case --- extract the entire array
extrac_errprint, 33, extrac[a, 0, 0, 0, 10, 10, 10], a
; Extract a completely interior region. This is what the subscript op does
extrac_errprint, 34, extrac[a, 2, 3, 4, 5, 6, 7], a[2:6,3:8,4:9]
end